package cn.yotta.user.core.server.iface.token;

import cn.yotta.common.utils.param.AssertUtil;
import cn.yotta.user.api.error.LoginErrorCode;
import cn.yotta.user.core.server.dto.token.TokenDto;
import cn.yotta.user.web.autoconfiguration.exception.UserLoginException;
import cn.yotta.user.web.autoconfiguration.utils.JwtUtil;
import com.google.common.collect.Maps;

import java.util.Map;
import java.util.Objects;

/**
 * @author wyaoyao
 * @date 2023/3/11 9:40
 */
public class JwyTokenGenerateStrategy implements TokenGenerateStrategy {

    protected static final String ISSUER = "Yotta";
    protected static final String SUBJECT = "LOGIN";
    protected static final String USERNAME_KEY = "username";
    protected static final String USER_ID_KEY = "userId";

    @Override
    public TokenDto generate(TokenGenParam genParam, Integer expireSecond) {
        AssertUtil.expectTrue(Objects.nonNull(expireSecond) && expireSecond >= 0, "Token expire time must greater than zero");
        final Map<String, String> claims = Maps.newHashMap();
        claims.put(USERNAME_KEY, genParam.getUsername());
        claims.put(USER_ID_KEY, String.valueOf(genParam.getUserId()));
        final String token = JwtUtil.generateToken(JwtUtil.JwtTokenGenParam.builder()
                .subject(SUBJECT)
                .issuer(ISSUER)
                .claims(claims)
                .expireSecond(expireSecond)
                .build());
        return new TokenDto(token, expireSecond);
    }


    @Override
    public TokenParseResult decode(String token) {
        final JwtUtil.JwtTokenParseParam parseParam = new JwtUtil.JwtTokenParseParam(token, SUBJECT);
        final JwtUtil.JwtParseResult decodeResult = JwtUtil.decode(parseParam);
        if (decodeResult.getIsExpired()) {
            // 已经过期
            throw new UserLoginException(LoginErrorCode.TOKEN_IS_EXPIRE.getCode());
        }
        final Map<String, String> claims = decodeResult.getClaims();
        final String username = claims.get(USERNAME_KEY);
        final Long userId = Long.valueOf(claims.get(USER_ID_KEY));
        return new TokenParseResult(token,userId, username);
    }
}
